﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using HamsterEngine.SimulationWindow;
using System.Threading;

namespace HamsterEngine.SimElements
{
    public class Hamster : SimElement
    {
        private int x, y;
        private HamsterOrientation orientation = HamsterOrientation.East;
        private Körner körnerImMaul = 0;

        public Körner KörnerImMaul
        {
            get { return körnerImMaul; }
            internal set { körnerImMaul = value; }
        }

        public HamsterOrientation Orientation
        {
            get { return orientation; }
            internal set { orientation = (HamsterOrientation)(((int)value) % 4); }
        }

        public Point Position
        {
            get
            {
                return new Point(x, y);
            }
            internal set
            {
                if (value.X == x && value.Y == y) return;
                if (Territorium.GetField(value.X, value.Y) != null && !(Territorium.GetField(value.X, value.Y) is Hamster))
                    throw new ArgumentException("Field must be empty!");
                Territorium.SetField(value.X, value.Y, this);
                Territorium.SetField(x, y, null);
                this.x = value.X;
                this.y = value.Y;
            }
        }

        public override Bitmap Image
        {
            get
            {
                Bitmap b = new Bitmap(1, 1);
                b.MakeTransparent(Color.White);
                for (int i = 0; i < (int)Orientation; i++)
                {
                    b.RotateFlip(RotateFlipType.Rotate270FlipNone);
                }
                return b;
            }
        }

        protected Hamster()
        {
            if (Territorium.Hamster.Length > 0)
            {
                this.x = Territorium.Hamster[0].x;
                this.y = Territorium.Hamster[0].y;
                this.orientation = Territorium.Hamster[0].orientation;
            }
            else
            {
                this.x = 0;
                this.y = 0;
                this.orientation = HamsterOrientation.East;
            }
        }

        public static Hamster CreateInstance(int x, int y, Color color, HamsterOrientation orientation = HamsterOrientation.East)
        {
            Hamster hamster = new Hamster();
            hamster.Position = new Point(x, y);
            hamster.orientation = orientation;
            return hamster;
        }

        public void Vor()
        {
            switch (Orientation)
            {
                case HamsterOrientation.East:
                    if (!(Territorium.GetField(x + 1, y) is Mauer))
                    {
                        Position = new Point(x + 1, y);
                    }
                    else
                    {
                        throw new MauerDaException("Es befindet sich eine Mauer auf dem Feld", new Point(x + 1, y), this);
                    }
                    break;
                case HamsterOrientation.South:
                    if (!(Territorium.GetField(x, y + 1) is Mauer))
                    {
                        Position = new Point(x, y + 1);
                    }
                    else
                    {
                        throw new MauerDaException("Es befindet sich eine Mauer auf dem Feld", new Point(x, y + 1), this);
                    }
                    break;
                case HamsterOrientation.West:
                    if (!(Territorium.GetField(x - 1, y) is Mauer))
                    {
                        Position = new Point(x - 1, y);
                    }
                    else
                    {
                        throw new MauerDaException("Es befindet sich eine Mauer auf dem Feld", new Point(x - 1, y), this);
                    }
                    break;
                case HamsterOrientation.North:
                    if (!(Territorium.GetField(x, y - 1) is Mauer))
                    {
                        Position = new Point(x, y - 1);
                    }
                    else
                    {
                        throw new MauerDaException("Es befindet sich eine Mauer auf dem Feld", new Point(x, y + 1), this);
                    }
                    break;
            }
            Simulation.methods.Add("Vor()");
            Thread.Sleep(Simulation.waitTime);
        }

        public void LinksUm()
        {
            this.Orientation++;
            Simulation.methods.Add("LinksUm()");
            Thread.Sleep(Simulation.waitTime);
        }

        public void Nimm()
        {
            if (Territorium.GetKörner(x, y).Amount > 0)
            {
                Territorium.SetField(x, y, new Körner(Territorium.GetKörner(x, y).Amount - 1));
            }
            else
            {
                throw new KachelLeerException("Auf der Kachel liegt kein Korn", Position, this);
            }

            Simulation.methods.Add("Nimm()");
            Thread.Sleep(Simulation.waitTime);
        }

        public void Gib()
        {
            if (körnerImMaul.Amount > 0)
            {
                körnerImMaul -= 1;
            }
            else
            {
                throw new MaulLeerException("Der Hamster hat keine Körner im Maul", Position, this);
            }

            Simulation.methods.Add("Gib()");
            Thread.Sleep(Simulation.waitTime);
        }

        public bool VornFrei
        {
            get
            {
                bool value = false;
                switch (Orientation)
                {
                    case HamsterOrientation.East:
                        value = !(Territorium.GetField(Position.X + 1, Position.Y) is Mauer); break;
                    case HamsterOrientation.North:
                        value = !(Territorium.GetField(Position.X, Position.Y - 1) is Mauer); break;
                    case HamsterOrientation.South:
                        value = !(Territorium.GetField(Position.X, Position.Y + 1) is Mauer); break;
                    case HamsterOrientation.West:
                        value = !(Territorium.GetField(Position.X - 1, Position.Y) is Mauer); break;
                }
                Simulation.methods.Add(string.Format("VornFrei() : {0}", value));
                Thread.Sleep(Simulation.waitTime);
                return value;
            }
        }


        public override string ToString()
        {
            return "Hamster: " + Position.ToString();
        }


    }

    public enum HamsterOrientation : int
    {
        East = 0,
        North = 1,
        West = 2,
        South = 3
    }

}
